import java.util.Arrays;

/**
 * @Auther: MFM
 * @Date: 2022/3/10 - 03 - 10 - 11:57
 * @version: 1.0
 */

public class ArrayDemo<E> {
    /*
     *   数组
     *   属性：容量 实际数量 是否为空
     *   方法：增删改查
     *   额外功能：自动扩容
     * */

    //底层 静态数组
    private E[] data;

    //实际数量
    private int size;

    //获得实际数量
    public int getSize() {
        return size;
    }

    //获得容量
    public int getCapacity() {
        return data.length;
    }

    //空构造函数
    public ArrayDemo(int capacity) throws Exception {
        setCapacity(capacity);
    }

    //初始化 设置容量
    public void setCapacity(int capacity) throws Exception {
        if (capacity < 0) {
            throw new Exception("索引越界");
        }
        data = (E[]) new Object[capacity];
        //初始化时容量为0
        size = 0;
    }

    //判断是否为空 是null显示true 不是null显示false
    public boolean isNull() {
        return data.length == 0;
    }

    //增加功能
    public boolean addData(int index, E e) throws Exception {
        if (index < 0) {
            throw new Exception("索引越界");
        }
        if (index > data.length) {
            E[] newData = (E[]) new Object[data.length + 10];

            for (int i = 0; i < size; i++) {
                newData[i] = data[i];
            }

            data = newData;
        }
        data[index] = e;
        size++;
        return true;

    }

    //在数组头部增加元素
    public boolean addFirst(E e) throws Exception {
        if (size < getCapacity()) {
            for (int i = size; i > 0; i--) {
                data[i] = data[i - 1];
            }
            data[0] = e;
            size++;
            return true;
        } else {
            //扩容
            E[] newData = (E[]) new Object[data.length + 10];

            for (int i = 0; i < size; i++) {
                newData[i] = data[i];
            }

            data = newData;
            //扩容完毕
            for (int i = size; i > 0; i--) {
                data[i + 1] = data[i];
            }
            data[0] = e;
            size++;
            return true;
        }

    }

    //在数组尾部增加元素
    public boolean addLast(E e) {
        if (size < getCapacity()) {
            data[size] = e;
            size++;
            return true;
        } else {
            //扩容
            E[] newData = (E[]) new Object[data.length + 10];

            for (int i = 0; i < size; i++) {
                newData[i] = data[i];
            }

            data = newData;
            //扩容完毕
            data[size] = e;
            size++;
            return true;
        }
    }

    //删除功能
    public E deleteData(int index) throws Exception {
        if (index>size-1){
            throw new Exception("该索引不存在元素");
        }

        E e = seeData(index);
        E[] newData = (E[]) new Object[data.length - 1];
        if (index + 1 == data.length) {
            //删除的是最后一个数据
            for (int i = 0; i < newData.length; i++) {
                newData[i] = data[i];
            }
            data = newData;
        } else {
            //删除的位置后面有元素
            for (int i = 0; i < index; i++) {
                //index 前元素复制
                newData[i] = data[i];
            }
            for (int i = index; i < data.length; i++) {
                //index 后元素复制
                newData[i - 1] = data[i];
            }
        }
        size--;
        return e;
    }

    //修改功能
    public boolean changeData(int index, E e) throws Exception {
        deleteData(index);
        addData(index, e);
        return true;
    }

    //查询功能
    public E seeData(int index) throws Exception {
        if (index > data.length || index < 0) {
            throw new Exception("索引越界");
        } else {
            return data[index];
        }
    }

    public int find(E e) {
        for (int i = 0; i < data.length; i++) {
            if (e.equals(data[i])) {

                //找到该元素返回索引i
                return i;
            }
        }

        //未找到该元素位置就返回-1
        return -1;
    }

    //找一堆 元素 传入一堆E 返回一个由索引构成的一个数组
    public int[] finds(E... es) {
        int[] arr = new int[es.length];
        int count = 0;
        for (int i = 0; i < es.length; i++) {
            for (int j = 0; j < data.length; j++) {
                if (es[i].equals(data[j])) {
                    arr[count] = j;
                    count++;
                }
            }
            if (i == count) {
                //将-1存入索引数组中表示未找到
                arr[count] = -1;
                count++;
            }
        }
        return arr;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("ArrayDemo{" + "data=");
        for (int i = 0; i < size; i++) {
            sb.append(data[i]);
            if (i!=size-1){
                sb.append(",");
            }
        }
        sb.append("}");

        return  sb.toString();
    }
}
